home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / yahp2ps / part05 < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  27.4 KB

  1. Path: xanth!nic.MR.NET!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Newsgroups: comp.sources.misc
  4. Subject: v06i007: HPGL to PostScript converter (Part 5 of 6)
  5. Message-ID: <46903@uunet.UU.NET>
  6. Date: 21 Jan 89 20:31:56 GMT
  7. Sender: allbery@uunet.UU.NET
  8. Reply-To: federico@actisb.UUCP (Federico Heinz)
  9. Organization: ACTIS in Berlin GmbH, W. Germany
  10. Lines: 1345
  11. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  12.  
  13. Posting-number: Volume 6, Issue 7
  14. Submitted-by: federico@actisb.UUCP (Federico Heinz)
  15. Archive-name: yahp2ps/part05
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 5 (of 6)."
  24. # Contents:  io.c penctrl.c
  25. # Wrapped by federico@actisb on Wed Jan  4 13:34:49 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'io.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'io.c'\"
  29. else
  30. echo shar: Extracting \"'io.c'\" \(12654 characters\)
  31. sed "s/^X//" >'io.c' <<'END_OF_FILE'
  32. X/*
  33. X        HPGL to PostScript converter
  34. X   Copyright (C) 1988 (and following) Federico Heinz
  35. X
  36. Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
  37. XWARRANTY.  No author or distributor accepts responsibility to anyone
  38. Xfor the consequences of using it or for whether it serves any
  39. Xparticular purpose or works at all, unless he says so in writing.
  40. XRefer to the Free Software Foundation's General Public License for full details.
  41. X
  42. XEveryone is granted permission to copy, modify and redistribute yahp2ps,
  43. Xbut only under the conditions described in the GNU General Public
  44. XLicense.  A copy of this license is supposed to have been given to you
  45. Xalong with yahp2ps so you can know your rights and responsibilities.  It
  46. Xshould be in a file named COPYING.  Among other things, the copyright
  47. Xnotice and this notice must be preserved on all copies.
  48. X
  49. XIn other words, go ahead and share yahp2ps, but don't try to stop
  50. Xanyone else from sharing it farther.  Help stamp out software hoarding!
  51. X
  52. Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
  53. Xit is only released under the same conditions.
  54. X
  55. X    For bug reports, wishes, etc. send e-mail to
  56. X
  57. X    ...!mcvax!unido!tub!actisb!federico  (from Europe)
  58. X    ...!uunet!pyramid!actisb!federico    (from anywhere else)
  59. X
  60. X    For Physical mail:
  61. X
  62. X    Federico Heinz
  63. X    Beusselstr. 21
  64. X    1000 Berlin 21
  65. X
  66. X    Tel. (+49 30) 396 77 92
  67. X
  68. X*/
  69. X/**************************************************************************
  70. X
  71. X  Input/Output functions.
  72. X
  73. X**************************************************************************/
  74. X
  75. X#include <stdio.h>
  76. X#include <ctype.h>
  77. X#include "defs.h"
  78. X#include "dispatch.h"
  79. X#include "io.h"
  80. X
  81. Xint LookAhead = 0;    /* Lookahead feature buffer */
  82. X
  83. X/*************************************************************************
  84. X
  85. X    Error handling
  86. X
  87. X*************************************************************************/
  88. X
  89. X
  90. X
  91. X/*
  92. X
  93. X  Put a non-fatal warning trough stderr.
  94. X
  95. X*/
  96. X
  97. Xvoid warning(text)
  98. X
  99. Xchar *text;
  100. X
  101. X{ fprintf(stderr, "hpgl2ps WARNING: %s\n", text);
  102. X}
  103. X
  104. X
  105. X
  106. X/*
  107. X
  108. X  Report a fatal error trough stderr.
  109. X
  110. X*/
  111. X
  112. Xvoid error(text)
  113. X
  114. Xchar *text;
  115. X
  116. X{ fprintf(stderr, "hpgl2ps ERROR: %s\n", text);
  117. X  exit(1);
  118. X}
  119. X
  120. X
  121. X/**************************************************************************
  122. X
  123. X    Basic file I/O
  124. X
  125. X**************************************************************************/
  126. X
  127. X
  128. Xstatic FILE *input = stdin;
  129. X
  130. Xstatic FILE *output = stdout;
  131. X
  132. X
  133. X/*
  134. X
  135. X  Get the next usable char from the file, skipping escape sequences.
  136. X
  137. X*/
  138. X
  139. Xstatic int getNextC()
  140. X
  141. X{ int c;
  142. X
  143. X  c = getc(input);
  144. X  while (c == '\033')
  145. X  { (void)getc(input); /* Ignore dot */
  146. X    switch (getc(input))
  147. X    { case '@':
  148. X      case 'H':
  149. X      case 'I':
  150. X      case 'M':
  151. X      case 'N': while (getc(input) != ':') ;
  152. X      case '(':
  153. X      case 'Y':
  154. X      case ')':
  155. X      case 'Z':
  156. X      case 'B':
  157. X      case 'E':
  158. X      case 'J':
  159. X      case 'K':
  160. X      case 'L':
  161. X      case 'O':
  162. X      case 'R': break;
  163. X      default: warning("Illegal escape sequence.");
  164. X    }
  165. X    c = getc(input);
  166. X    while(isTerminator(c)) c = getc(input);
  167. X  }
  168. X  return(c);
  169. X}
  170. X          
  171. X
  172. X/*
  173. X
  174. X  Get the next char from the input stream with lookahead
  175. X
  176. X*/
  177. X
  178. Xint getChar()
  179. X
  180. X{ int   aChar;
  181. X
  182. X  if (!LookAhead) LookAhead = getNextC();
  183. X  aChar = LookAhead;
  184. X  if (LookAhead != EOF) LookAhead = getNextC();
  185. X  return(aChar);
  186. X}
  187. X
  188. X
  189. X
  190. X
  191. X/*
  192. X
  193. X  Put a char to the output stream.
  194. X
  195. X*/
  196. X
  197. Xvoid putChar(c)
  198. X
  199. Xchar c;
  200. X
  201. X{ putc(c, output); }
  202. X
  203. X
  204. X
  205. X/*************************************************************************
  206. X
  207. X   HPGL syntax sensitive stuff
  208. X
  209. X*************************************************************************/
  210. X
  211. X
  212. X
  213. X/*
  214. X
  215. X  Skip over optional separator.
  216. X
  217. X*/
  218. X
  219. Xvoid skipSeparator()
  220. X
  221. X{ while (isSeparator(LookAhead)) (void)getChar(); }
  222. X
  223. X
  224. X
  225. X/*
  226. X
  227. X  Skip over statement terminator.
  228. X
  229. X*/
  230. X
  231. Xvoid skipTerminator()
  232. X
  233. X{ while (isTerminator(LookAhead))
  234. X  { (void)getChar();
  235. X    skipSeparator();
  236. X  }
  237. X}
  238. X
  239. X
  240. X/*************************************************************************
  241. X
  242. X  Number input
  243. X
  244. X*************************************************************************/
  245. X
  246. X
  247. X/* Powers of ten */
  248. X
  249. Xstatic  long int TenToThe[] = { 1L, 10L, 100L, 1000L, 10000L };
  250. X
  251. X
  252. X
  253. X/*
  254. X
  255. X  Read a Number from the input stream.
  256. X
  257. X*/
  258. X
  259. X
  260. XBoolean getNumber(target)
  261. X
  262. XNumber *target;
  263. X
  264. X{ Number result;
  265. X  int    placesLeft, decimalsLeft;
  266. X  Boolean negative;
  267. X
  268. X  if (LookAhead == '+')
  269. X  { negative = False;
  270. X    getChar();
  271. X  }
  272. X  else if (LookAhead == '-')
  273. X  { negative = True;
  274. X    getChar();
  275. X  }
  276. X  if (!isdigit(LookAhead) && (LookAhead != '.'))
  277. X  { warning("Number expected.");
  278. X    return(False);
  279. X  }
  280. X  result = 0; placesLeft = IntPlaces;
  281. X  while (isdigit(LookAhead) && placesLeft)
  282. X  { result = result * 10L + (Number)(getChar() - '0');
  283. X    placesLeft--;
  284. X  }
  285. X  if (isdigit(LookAhead)) 
  286. X  { warning("Number out of range.");
  287. X    return(False);
  288. X  }
  289. X  decimalsLeft = DecPlaces;
  290. X  if (LookAhead == '.')
  291. X  { (void)getChar();
  292. X    while(isdigit(LookAhead) && decimalsLeft)
  293. X    { result = result * 10L + (Number)(getChar() - '0');
  294. X      decimalsLeft--;
  295. X    }
  296. X    if (isdigit(LookAhead))
  297. X    { warning("Extra decimal places skipped.");
  298. X      while(isdigit(LookAhead)) (void)getChar();
  299. X    }
  300. X  }
  301. X  skipSeparator();
  302. X  *target = (negative ? -result : result) * TenToThe[decimalsLeft];
  303. X  return(True);
  304. X}
  305. X
  306. X
  307. X/*
  308. X
  309. X  Convert from ASCII to Number.
  310. X
  311. X*/
  312. X
  313. XBoolean ASCIIToNumber(target, source)
  314. X
  315. XNumber *target;
  316. Xchar **source;
  317. X
  318. X{ Number result;
  319. X  int    placesLeft, decimalsLeft;
  320. X
  321. X  result = 0; placesLeft = IntPlaces;
  322. X  while (isdigit(**source) && placesLeft)
  323. X  { result = result * 10L + (Number)((*((*source)++)) - '0');
  324. X    placesLeft--;
  325. X  }
  326. X  if (isdigit(**source))
  327. X    return(False);
  328. X  decimalsLeft = DecPlaces;
  329. X  if (**source == '.')
  330. X  { (*source)++;
  331. X    while(isdigit(**source) && decimalsLeft)
  332. X    { result = result * 10L + (Number)((*((*source)++)) - '0');
  333. X      decimalsLeft--;
  334. X    }
  335. X    while(isdigit(**source)) (*source)++;
  336. X  }
  337. X  *target = result * TenToThe[decimalsLeft];
  338. X  return(True);
  339. X}
  340. X
  341. X
  342. X
  343. X/*
  344. X
  345. X  Read an Integer
  346. X
  347. X*/
  348. X
  349. XBoolean getInteger(target)
  350. X
  351. XNumber *target;
  352. X
  353. X{ Number result;
  354. X
  355. X  if (getNumber(&result))
  356. X  { *target = trunc(result);
  357. X    return(True);
  358. X  }
  359. X  else
  360. X    return(False);
  361. X}
  362. X
  363. X
  364. X
  365. X/*
  366. X
  367. X  Read a CoordinatePair.
  368. X
  369. X*/
  370. X
  371. XBoolean getCoordinatePair(target)
  372. X
  373. XCoordinatePair target;
  374. X
  375. X{ if (!getNumber(&target[X])) return(False);
  376. X  skipSeparator();
  377. X  if (!isNumeric(LookAhead))
  378. X  { warning("Uneven number of coordinates.");
  379. X    return(False);
  380. X  }
  381. X  return(getNumber(&target[Y]));
  382. X}
  383. X
  384. X
  385. X/***************************************************************************
  386. X
  387. X   Number output
  388. X
  389. X**************************************************************************/
  390. X
  391. X   
  392. X
  393. X
  394. X/*
  395. X
  396. X  Private routine to put a positive integer to the output stream. A zero
  397. X  produces no output at all. No space is appended at the end.
  398. X
  399. X*/
  400. X
  401. Xstatic void putInt(n)
  402. X
  403. Xint n;
  404. X
  405. X{ if (n)
  406. X  { putInt(n / 10);
  407. X    putChar((n % 10) + '0');
  408. X  }
  409. X}
  410. X
  411. X
  412. X
  413. X/*
  414. X
  415. X  Write a Number to the output stream.
  416. X
  417. X*/
  418. X
  419. Xvoid writeNumber(n)
  420. X
  421. XNumber n;
  422. X
  423. X{ int integerPart, fractionalPart;
  424. X
  425. X  if (n == Zero)
  426. X    putChar('0');
  427. X  else
  428. X  { if (n < Zero)
  429. X    { putChar('-');
  430. X      n = -n;
  431. X    }
  432. X    integerPart = (int)(n / One);
  433. X    fractionalPart = (int)(n % One);
  434. X    putInt(integerPart);
  435. X    if (fractionalPart)
  436. X    { putChar('.');
  437. X      while (!(fractionalPart % 10)) fractionalPart /= 10;
  438. X      putInt(fractionalPart);
  439. X    }
  440. X  }
  441. X  putChar(' ');
  442. X}
  443. X
  444. X
  445. X
  446. X/*
  447. X
  448. X  Write a CoordinatePair to the output stream.
  449. X
  450. X*/
  451. X
  452. Xvoid writeCoordinatePair(source)
  453. X
  454. XCoordinatePair  source;
  455. X
  456. X{ writeNumber(source[X]);
  457. X  writeNumber(source[Y]);
  458. X}
  459. X
  460. X
  461. X
  462. X/*
  463. X
  464. X  Write an integer to the output string.
  465. X
  466. X*/
  467. X
  468. Xvoid writeInt(n)
  469. X
  470. Xint n;
  471. X
  472. X{ if (n = 0)
  473. X    putChar('0');
  474. X  else
  475. X    if (n < 0)
  476. X    { putChar('-');
  477. X      n = -n;
  478. X    }
  479. X    putInt(n);
  480. X  putChar(' ');
  481. X}
  482. X
  483. X
  484. X/**************************************************************************
  485. X
  486. X  String output.
  487. X
  488. X**************************************************************************/
  489. X
  490. X
  491. X
  492. X/*
  493. X
  494. X  Write a string to the output stream.
  495. X
  496. X*/
  497. X
  498. Xvoid writeString(x)
  499. X
  500. Xchar *x;
  501. X
  502. X{ while (*x) putChar(*(x++)); }
  503. X
  504. X
  505. X/*************************************************************************
  506. X
  507. X   Command input
  508. X
  509. X*************************************************************************/
  510. X
  511. X
  512. X
  513. X/*
  514. X
  515. X  Get and decode a command from the input stream.
  516. X
  517. X*/
  518. X
  519. Xstatic struct CommandItem
  520. X{ int           key;
  521. X  Command       code;
  522. X} ACommands[] =
  523. X  { {'A', ArcAbsolute },
  524. X    {'R', ArcRelative },
  525. X    { 0, 0 }
  526. X  },
  527. X
  528. X  CCommands[] =
  529. X  { {'A', SetAlternateChar },
  530. X    {'I', Circle },
  531. X    {'P', CharacterPlot },
  532. X    {'S', SetStandardChar },
  533. X    { 0, 0 }
  534. X  },
  535. X
  536. X  DCommands[] =
  537. X  { {'C', NotImplemented },             /* Digitize Clear */
  538. X    {'F', SetDefaults },
  539. X    {'I', SetAbsoluteDirection },
  540. X    {'P', NotImplemented },             /* Digitize Point */
  541. X    {'R', SetRelativeDirection },
  542. X    {'T', SetLabelTerminator },
  543. X    { 0, 0 }
  544. X  },
  545. X
  546. X  ECommands[] =
  547. X  { {'A', RectangleAbsolute },
  548. X    {'R', RectangleRelative },
  549. X    {'W', Wedge },
  550. X    { 0, 0 }
  551. X  },
  552. X
  553. X  FCommands[] =
  554. X  { {'T', SetFillType },
  555. X    { 0, 0 }
  556. X  },
  557. X
  558. X  ICommands[] =
  559. X  { {'M', NotImplemented },             /* Input Mask */
  560. X    {'N', Initialize },
  561. X    {'P', InputP1P2 },
  562. X    {'W', InputWindow },
  563. X    { 0, 0 }
  564. X  },
  565. X
  566. X  LCommands[] =
  567. X  { {'B', PutASCIILabel },
  568. X    {'T', SetLineType },
  569. X    { 0, 0 }
  570. X  },
  571. X
  572. X  OCommands[] =
  573. X  { {'A', Interactive },                /* Output Position  */
  574. X    {'C', Interactive },                /* Output Commanded */
  575. X    {'D', Interactive },                /* Output Point     */
  576. X    {'E', Interactive },                /* Output Error     */
  577. X    {'F', Interactive },                /* Output Factors   */
  578. X    {'H', Interactive },                /* Output Hard Clip */
  579. X    {'I', Interactive },                /* Output Ident     */
  580. X    {'O', Interactive },                /* Output Options   */
  581. X    {'P', Interactive },                /* Output P1 and P2 */
  582. X    {'S', Interactive },                /* Output Status    */
  583. X    {'W', Interactive },                /* Output Window    */
  584. X    { 0, 0 }
  585. X  },
  586. X
  587. X  PCommands[] =
  588. X  { {'A', SetAbsolutePlot },
  589. X    {'D', PenDown },
  590. X    {'R', SetRelativePlot },
  591. X    {'S', SetPaperSize },
  592. X    {'T', PenThickness },             /* Pen Thickness */
  593. X    {'U', PenUp },
  594. X    { 0, 0 }
  595. X  },
  596. X
  597. X  RCommands[] =
  598. X  { {'A', ShadeRectAbsolute },
  599. X    {'O', RotateCoordSys },
  600. X    {'R', ShadeRectRelative },
  601. X    { 0, 0 }
  602. X  },
  603. X
  604. X  SCommands[] =
  605. X  { {'A', SelectAlternate },
  606. X    {'C', SetScale },
  607. X    {'I', SetAbsoluteCharSize },
  608. X    {'L', SetAbsoluteCharSlant },
  609. X    {'M', SetSymbolMode },
  610. X    {'P', SelectPen },
  611. X    {'R', SetRelativeCharSize },
  612. X    {'S', SelectStandard },
  613. X    { 0, 0 }
  614. X  },
  615. X
  616. X  TCommands[] =
  617. X  { {'L', SetTickLength },
  618. X    { 0, 0 }
  619. X  },
  620. X
  621. X  UCommands[] =
  622. X  { {'C', UserChar },
  623. X    { 0, 0 }
  624. X  },
  625. X
  626. X  VCommands[] =
  627. X  { {'S', NotImplemented },             /* Set Velocity */
  628. X    { 0, 0 }
  629. X  },
  630. X
  631. X  WCommands[] =
  632. X  { {'G', ShadeWedge },
  633. X    { 0, 0 }
  634. X  },
  635. X
  636. X  XCommands[] =
  637. X  { {'T', XTick },
  638. X    { 0, 0 }
  639. X  },
  640. X
  641. X  YCommands[] =
  642. X  { {'T', YTick },
  643. X    { 0, 0 }
  644. X  },
  645. X
  646. X  *CommandIndex[] =
  647. X    {   ACommands,
  648. X        NULL, 
  649. X        CCommands, 
  650. X        DCommands, 
  651. X        ECommands,
  652. X        FCommands, 
  653. X        NULL, 
  654. X        NULL, 
  655. X        ICommands, 
  656. X        NULL, 
  657. X        NULL, 
  658. X        LCommands,
  659. X        NULL, 
  660. X        NULL, 
  661. X        OCommands, 
  662. X        PCommands, 
  663. X        NULL, 
  664. X        RCommands,
  665. X        SCommands, 
  666. X        TCommands, 
  667. X        UCommands, 
  668. X        VCommands,
  669. X        WCommands, 
  670. X        XCommands, 
  671. X        YCommands, 
  672. X        NULL
  673. X    };
  674. X
  675. X
  676. X
  677. XCommand getCommand()
  678. X
  679. X{ int                   c;
  680. X  struct CommandItem    *tablePointer;
  681. X
  682. X  c = getChar();
  683. X  if (isalpha(c) &&
  684. X     ((tablePointer = CommandIndex[islower(c) ? (c - 'a') : (c - 'A')]) != NULL))
  685. X  { skipSeparator();
  686. X    c = getChar();
  687. X    if (isalpha(c))
  688. X    { if (islower(c)) c = toupper(c);
  689. X      while (tablePointer->key)
  690. X        if (tablePointer->key == c)
  691. X        { skipSeparator();
  692. X          return(tablePointer->code);
  693. X        }
  694. X        else
  695. X          tablePointer++;
  696. X    }
  697. X  }
  698. X  error("Illegal HPGL command.");
  699. X}
  700. X
  701. X
  702. X
  703. X/*
  704. X
  705. X  Handle extra parameters to a command.
  706. X
  707. X*/
  708. X
  709. Xvoid endCommand()
  710. X
  711. X{ Number dummy;
  712. X
  713. X  if (!isTerminator(LookAhead))
  714. X  { warning("Extra parameters ignored");
  715. X    while (!isTerminator(LookAhead))
  716. X      (void)getChar();
  717. X  }
  718. X  skipTerminator();
  719. X}
  720. X
  721. X
  722. X
  723. X/*************************************************************************
  724. X
  725. X  Internal I/O redirection
  726. X
  727. X*************************************************************************/
  728. X
  729. X
  730. X/*
  731. X
  732. X  Get input chars from specified file.
  733. X
  734. X*/
  735. X
  736. XBoolean setInput(fileName)
  737. X
  738. Xchar *fileName;
  739. X
  740. X{ return((input = fopen(fileName,"r")) != NULL); }
  741. X
  742. X
  743. X
  744. X/*
  745. X
  746. X  Put output chars to specified file.
  747. X
  748. X*/
  749. X
  750. XBoolean setOutput(fileName)
  751. X
  752. Xchar *fileName;
  753. X
  754. X{ return((output = fopen(fileName,"w")) != NULL); }
  755. X
  756. END_OF_FILE
  757. if test 12654 -ne `wc -c <'io.c'`; then
  758.     echo shar: \"'io.c'\" unpacked with wrong size!
  759. fi
  760. # end of 'io.c'
  761. fi
  762. if test -f 'penctrl.c' -a "${1}" != "-c" ; then 
  763.   echo shar: Will not clobber existing file \"'penctrl.c'\"
  764. else
  765. echo shar: Extracting \"'penctrl.c'\" \(11891 characters\)
  766. sed "s/^X//" >'penctrl.c' <<'END_OF_FILE'
  767. X/*
  768. X        HPGL to PostScript converter
  769. X   Copyright (C) 1988 (and following) Federico Heinz
  770. X
  771. Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
  772. XWARRANTY.  No author or distributor accepts responsibility to anyone
  773. Xfor the consequences of using it or for whether it serves any
  774. Xparticular purpose or works at all, unless he says so in writing.
  775. XRefer to the Free Software Foundation's General Public License for full details.
  776. X
  777. XEveryone is granted permission to copy, modify and redistribute yahp2ps,
  778. Xbut only under the conditions described in the GNU General Public
  779. XLicense.  A copy of this license is supposed to have been given to you
  780. Xalong with yahp2ps so you can know your rights and responsibilities.  It
  781. Xshould be in a file named COPYING.  Among other things, the copyright
  782. Xnotice and this notice must be preserved on all copies.
  783. X
  784. XIn other words, go ahead and share yahp2ps, but don't try to stop
  785. Xanyone else from sharing it farther.  Help stamp out software hoarding!
  786. X
  787. Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
  788. Xit is only released under the same conditions.
  789. X
  790. X    For bug reports, wishes, etc. send e-mail to
  791. X
  792. X    ...!mcvax!unido!tub!actisb!federico  (from Europe)
  793. X    ...!uunet!pyramid!actisb!federico    (from anywhere else)
  794. X
  795. X    For Physical mail:
  796. X
  797. X    Federico Heinz
  798. X    Beusselstr. 21
  799. X    1000 Berlin 21
  800. X
  801. X    Tel. (+49 30) 396 77 92
  802. X
  803. X*/
  804. X
  805. X/***************************************************************************
  806. X
  807. X  Primitive pen control routines. Provides the interface between the
  808. X  ideal plotter and the machinery.
  809. X
  810. X****************************************************************************/
  811. X
  812. X#include "defs.h"
  813. X#include "mchinery.h"
  814. X#include "penctrl.h"
  815. X#include "circle.h"
  816. X#include "tick.h"
  817. X#include "io.h"
  818. X
  819. X
  820. X/***************************************************************************
  821. X
  822. X   Data defining the plotter's status.
  823. X
  824. X***************************************************************************/
  825. X
  826. X
  827. X                    /* Current plotting pen's coordinates */
  828. XCoordinatePair PenPosition = { Zero, Zero };
  829. X
  830. X                                     /* Pn's position in User Space */
  831. Xstatic CoordinatePair UserP1, UserP2;
  832. X
  833. X                                     /* Pn's coords in Plotter Space */
  834. XCoordinatePair PlotterP1, PlotterP2;
  835. X
  836. X                     /* P1-P2 distance              */
  837. XNumber      P1P2Diagonal;
  838. X
  839. X                     /* Size of paper in use        */
  840. Xstatic int        PaperSize = A4;
  841. X
  842. Xstatic Number LineType;            /* Line type used for stroking */
  843. Xstatic Number LinePatternLength;   /* Length of a pattern cicle   */
  844. Xstatic Number PenHeld = Zero;      /* Pen we're holding           */
  845. X
  846. X
  847. X       Boolean UserMode = False;     /* Plotting in User Space?           */
  848. Xstatic Boolean Rotated = False;      /* Is the plot rotated 90 degrees?   */
  849. X       Boolean PenIsUp = True;       /* Is the plotting pen up?           */
  850. Xstatic Boolean LineDrawn = False;    /* Have we drawn a line?          */
  851. X
  852. XCoordinatePair FurthestPoint[] = { { MaxXA,  MaxYA },
  853. X                                   { MaxXA4, MaxYA4 },
  854. X                                   { MaxXB,  MaxYB },
  855. X                                   { MaxXA3, MaxXA3 } };
  856. X
  857. XCoordinatePair FurthestPointRotated[] =
  858. X                                 { { MaxYA,  MaxXA },
  859. X                                   { MaxYA4, MaxXA4 },
  860. X                                   { MaxYB,  MaxXB },
  861. X                                   { MaxXA3, MaxXA3 } };
  862. X
  863. XCoordinatePair DefaultP1[] = { {InitialP1XA,  InitialP1YA},
  864. X                   {InitialP1XA4, InitialP1YA4},
  865. X                   {InitialP1XB,  InitialP1YB},
  866. X                   {InitialP1XA3, InitialP1YA3} };
  867. X
  868. XCoordinatePair DefaultP2[] = { {InitialP2XA,  InitialP2YA},
  869. X                   {InitialP2XA4, InitialP2YA4},
  870. X                   {InitialP2XB,  InitialP2YB},
  871. X                   {InitialP2XA3, InitialP2YA3} };
  872. X
  873. XCoordinatePair DefaultP1Rotated[] =
  874. X                             { {InitialP1XAR,  InitialP1YAR},
  875. X                   {InitialP1XA4R, InitialP1YA4R},
  876. X                   {InitialP1XBR,  InitialP1YBR},
  877. X                   {InitialP1XA3R, InitialP1YA3R} };
  878. X
  879. XCoordinatePair DefaultP2Rotated[] =
  880. X                             { {InitialP2XAR,  InitialP2YAR},
  881. X                   {InitialP2XA4R, InitialP2YA4R},
  882. X                   {InitialP2XBR,  InitialP2YBR},
  883. X                   {InitialP2XA3R, InitialP2YA3R} };
  884. X
  885. X
  886. X/**************************************************************************
  887. X
  888. X   Paper size.
  889. X
  890. X/*************************************************************************/
  891. X
  892. X
  893. Xvoid changePaperSize(newPaperSize)
  894. X
  895. Xint newPaperSize;
  896. X
  897. X{ PaperSize = newPaperSize; }
  898. X
  899. X
  900. X
  901. X/***************************************************************************
  902. X
  903. X   Pen changing.
  904. X
  905. X***************************************************************************/
  906. X
  907. X/*
  908. X
  909. X  Each pen's width and color.
  910. X
  911. X*/
  912. X  
  913. Xstatic Number PenWidth[MaxPen/One] = { 2500, 3500, 5000,
  914. X                       7500, 10000, 20000 };
  915. Xstatic Number PenColor[MaxPen/One] = { Zero, Zero, Zero, Zero, Zero, Zero };
  916. X
  917. X
  918. X
  919. X/*
  920. X
  921. X  Change the pen sizes.
  922. X
  923. X*/
  924. X
  925. Xvoid getPenSizes(string)
  926. X
  927. Xchar *string;
  928. X
  929. X{ int i;
  930. X
  931. X  i = 0;
  932. X  while (*string && (i < (MaxPen/One)))
  933. X    if (!ASCIIToNumber(&PenWidth[i++], &string))
  934. X      error("Illegal pen width.");
  935. X}
  936. X
  937. X
  938. X
  939. X/*
  940. X
  941. X  Get a new pen
  942. X
  943. X */
  944. X
  945. Xvoid changePen(pen)
  946. X
  947. XNumber pen;
  948. X
  949. X{ Boolean penWasDown;
  950. X  int oldPen;
  951. X
  952. X  if (pen == PenHeld)
  953. X    return;
  954. X  if ((penWasDown = !PenIsUp)) liftPen();
  955. X  if ((pen > Zero) && (pen <= MaxPen))
  956. X  { oldPen = (PenHeld/One) - 1;
  957. X    PenHeld = pen;
  958. X    pen = (pen / One ) - 1;
  959. X    if (PenWidth[pen] != PenWidth[oldPen])
  960. X      setPenWidth(PenWidth[pen]);
  961. X    if (PenColor[pen] != PenColor[oldPen])
  962. X      setPenColor(PenColor[pen]);
  963. X  }
  964. X  else if (!pen)
  965. X    PenHeld = Zero;
  966. X  else
  967. X    warning("Pen number out of range.");
  968. X  if (penWasDown) lowerPen();
  969. X}
  970. X
  971. X
  972. X
  973. X/*
  974. X
  975. X  Update the pattern to new parameters.
  976. X
  977. X*/
  978. X
  979. Xstatic void updateLinePattern()
  980. X
  981. X{ Boolean penWasDown;
  982. X
  983. X  if ((penWasDown = !PenIsUp)) liftPen();
  984. X  setPattern(LineType, mulNum(LinePatternLength, P1P2Diagonal)/100);
  985. X  if (penWasDown) lowerPen();
  986. X}
  987. X
  988. X
  989. X
  990. X/*
  991. X
  992. X  Change the line pattern
  993. X
  994. X */
  995. X
  996. Xvoid setDash(pattern, patternLength)
  997. X
  998. XNumber pattern, patternLength;
  999. X
  1000. X{ Boolean penWasDown;
  1001. X
  1002. X  if ((LineType == pattern) &&
  1003. X      ((patternLength <= 0) ||
  1004. X       (patternLength >= (128*One)) ||
  1005. X       (patternLength == LinePatternLength)))
  1006. X    return;
  1007. X  if ((patternLength > 0) && (patternLength < (128*One)))
  1008. X    LinePatternLength = patternLength;
  1009. X  LineType = pattern;
  1010. X  updateLinePattern();
  1011. X}
  1012. X
  1013. X
  1014. X
  1015. X/**************************************************************************
  1016. X
  1017. X   Clipping rectangle.
  1018. X
  1019. X**************************************************************************/
  1020. X
  1021. Xstatic CoordinatePair Origin = { Zero, Zero };
  1022. X
  1023. X
  1024. X/*
  1025. X
  1026. X  Set a new clipping rectangle.
  1027. X
  1028. X*/
  1029. X
  1030. Xvoid setWindow(corner1, corner2)
  1031. X
  1032. XCoordinatePair corner1, corner2;
  1033. X
  1034. X{ setClip(corner1, corner2); }
  1035. X
  1036. X
  1037. X
  1038. X/*
  1039. X
  1040. X  Set the clipping rectangle to the whole plotting area.
  1041. X
  1042. X*/
  1043. X
  1044. Xvoid resetWindow()
  1045. X
  1046. X{ 
  1047. X  if (Rotated)
  1048. X    setWindow(Origin, FurthestPointRotated[PaperSize]);
  1049. X  else
  1050. X    setWindow(Origin, FurthestPoint[PaperSize]);
  1051. X}
  1052. X
  1053. X
  1054. X
  1055. X/**************************************************************************
  1056. X
  1057. X  Scaling of User Space.
  1058. X
  1059. X**************************************************************************/
  1060. X
  1061. X
  1062. X/* Parameters for scaling */
  1063. X
  1064. XNumber XScaleFactor = One, YScaleFactor = One;
  1065. XNumber XOrigin = Zero, YOrigin = Zero;
  1066. X
  1067. X
  1068. X
  1069. X/*
  1070. X
  1071. X  Convert from plotter coordinates to user coordinates.
  1072. X
  1073. X*/
  1074. X
  1075. Xstatic void plotterToUser(target, plotterPoint)
  1076. X
  1077. XCoordinatePair target, plotterPoint;
  1078. X
  1079. X{
  1080. X  target[X] = divNum(plotterPoint[X] - XOrigin, XScaleFactor);
  1081. X  target[Y] = divNum(plotterPoint[Y] - YOrigin, YScaleFactor);
  1082. X}
  1083. X
  1084. X
  1085. X
  1086. X/*
  1087. X
  1088. X  Set the scaling parameters to the appropriate values.
  1089. X
  1090. X*/
  1091. X
  1092. Xvoid updateScaling()
  1093. X
  1094. X{ CoordinatePair plotterPenPosition;
  1095. X
  1096. X  if (UserMode)
  1097. X  { plotterPenPosition[X] = plotterXCoord(PenPosition[X]);
  1098. X    plotterPenPosition[Y] = plotterYCoord(PenPosition[Y]);
  1099. X    XScaleFactor = divNum((PlotterP2[X] - PlotterP1[X]),
  1100. X                          (UserP2[X] - UserP1[X]));
  1101. X    XOrigin = PlotterP1[X] - mulNum(XScaleFactor, UserP1[X]);
  1102. X    YScaleFactor = divNum((PlotterP2[Y] - PlotterP1[Y]),
  1103. X                          (UserP2[Y] - UserP1[Y]));
  1104. X    YOrigin = PlotterP1[Y] - mulNum(YScaleFactor, UserP1[Y]);
  1105. X    plotterToUser(PenPosition, plotterPenPosition);
  1106. X  }
  1107. X}
  1108. X
  1109. X
  1110. X
  1111. X/*
  1112. X
  1113. X  From now on, coordinates won't be scaled any more.
  1114. X
  1115. X*/
  1116. X
  1117. Xvoid turnScalingOff()
  1118. X
  1119. X{ PenPosition[X] = plotterXCoord(PenPosition[X]);
  1120. X  PenPosition[Y] = plotterYCoord(PenPosition[Y]);
  1121. X  UserMode = False;
  1122. X}
  1123. X
  1124. X
  1125. X
  1126. X/*
  1127. X
  1128. X  From now on, coordinates will be scaled according to the user's taste.
  1129. X
  1130. X*/
  1131. X
  1132. Xvoid turnScalingOn(newUserP1, newUserP2)
  1133. X
  1134. XCoordinatePair newUserP1, newUserP2;
  1135. X
  1136. X{ if ((newUserP1[X] == newUserP2[X]) || (newUserP1[Y] == newUserP2[Y]))
  1137. X    warning("Invalid scale parameters.");
  1138. X  else
  1139. X  { UserMode = True;
  1140. X    UserP1[X] = newUserP1[X];
  1141. X    UserP1[Y] = newUserP1[Y];
  1142. X    UserP2[X] = newUserP2[X];
  1143. X    UserP2[Y] = newUserP2[Y];
  1144. X    updateScaling();
  1145. X  }
  1146. X}
  1147. X
  1148. X
  1149. X
  1150. X/*
  1151. X
  1152. X  Change the scaling points and update everything needed.
  1153. X
  1154. X*/
  1155. X
  1156. Xvoid changeP1P2(newP1, newP2)
  1157. X
  1158. XCoordinatePair newP1, newP2;
  1159. X
  1160. X{ Number dummy;
  1161. X  CoordinatePair delta;
  1162. X  
  1163. X  PlotterP1[X] = newP1[X];
  1164. X  PlotterP1[Y] = newP1[Y];
  1165. X  PlotterP2[X] = newP2[X];
  1166. X  PlotterP2[Y] = newP2[Y];
  1167. X  delta[X] = PlotterP2[X] - PlotterP1[X];
  1168. X  delta[Y] = PlotterP2[Y] - PlotterP1[Y];
  1169. X  cartesianToPolar(&P1P2Diagonal, &dummy, delta);
  1170. X  updateScaling();
  1171. X  updateTicks();
  1172. X  updateLinePattern();
  1173. X}
  1174. X
  1175. X
  1176. X
  1177. X/*
  1178. X
  1179. X  Rotate the coordinate system.
  1180. X
  1181. X*/
  1182. X
  1183. Xvoid rotate()
  1184. X
  1185. X{ CoordinatePair plotterPenPosition;
  1186. X  
  1187. X  if (!Rotated)
  1188. X  { plotterPenPosition[Y] = plotterXCoord(PenPosition[X]);
  1189. X    plotterPenPosition[X] = FurthestPoint[PaperSize][Y] -
  1190. X                                plotterYCoord(PenPosition[Y]);
  1191. X    plotterToUser(PenPosition, plotterPenPosition);
  1192. X    doRotation();
  1193. X    correctClip();
  1194. X    Rotated = True;
  1195. X  }
  1196. X}
  1197. X
  1198. X
  1199. X
  1200. X/*
  1201. X
  1202. X  Return paper to default orientation.
  1203. X
  1204. X*/
  1205. X
  1206. Xvoid unRotate()
  1207. X
  1208. X{ CoordinatePair plotterPenPosition;
  1209. X  
  1210. X  if (Rotated)
  1211. X  { plotterPenPosition[X] = plotterYCoord(PenPosition[Y]);
  1212. X    plotterPenPosition[Y] = FurthestPoint[PaperSize][Y] -
  1213. X                                plotterXCoord(PenPosition[X]);
  1214. X    plotterToUser(PenPosition, plotterPenPosition);
  1215. X    undoRotation();
  1216. X    correctClip();
  1217. X    Rotated = False;
  1218. X  }
  1219. X}
  1220. X
  1221. X
  1222. X/**************************************************************************
  1223. X
  1224. X  Plotter status initialization.
  1225. X
  1226. X**************************************************************************/
  1227. X
  1228. X
  1229. X
  1230. X/*
  1231. X
  1232. X  Set the scaling points to the default values.
  1233. X
  1234. X*/
  1235. X
  1236. Xvoid resetP1P2()
  1237. X
  1238. X{ if (Rotated)
  1239. X    changeP1P2(DefaultP1Rotated[PaperSize], DefaultP2Rotated[PaperSize]);
  1240. X  else
  1241. X    changeP1P2(DefaultP1[PaperSize], DefaultP2[PaperSize]);
  1242. X}
  1243. X
  1244. X
  1245. X/*
  1246. X
  1247. X  Set default parameters of this module's stuff.
  1248. X
  1249. X*/
  1250. X
  1251. Xvoid penctrlInit()
  1252. X
  1253. X{ liftPen();
  1254. X  resetP1P2();
  1255. X  unRotate();
  1256. X}
  1257. X
  1258. X
  1259. X
  1260. X/**************************************************************************
  1261. X
  1262. X  Moving the pen around.
  1263. X
  1264. X**************************************************************************/
  1265. X
  1266. X
  1267. X
  1268. X/*
  1269. X
  1270. X  Move the logical pen in it's current state to some place in User Space.
  1271. X
  1272. X*/
  1273. X
  1274. Xvoid doLine(targetX, targetY)
  1275. X
  1276. XNumber targetX, targetY;
  1277. X
  1278. X{ Number absoluteTargetX, absoluteTargetY;
  1279. X
  1280. X  if (!PenIsUp && PenHeld)
  1281. X  { LineDrawn = True; 
  1282. X    if (LineType)
  1283. X      drawLine(plotterXCoord(targetX),
  1284. X               plotterYCoord(targetY));
  1285. X    else            /* Linetype 0: just dots at coords */
  1286. X    { liftPen();
  1287. X      PenPosition[X] = targetX;
  1288. X      PenPosition[Y] = targetY;
  1289. X      lowerPen();
  1290. X      return;
  1291. X    }
  1292. X  }
  1293. X  PenPosition[X] = targetX;
  1294. X  PenPosition[Y] = targetY;
  1295. X}
  1296. X
  1297. X
  1298. X
  1299. X/*
  1300. X
  1301. X  Lift the plotting pen.
  1302. X
  1303. X*/
  1304. X
  1305. Xvoid liftPen()
  1306. X
  1307. X{ if (!PenIsUp)
  1308. X  { if (LineDrawn)
  1309. X      LineDrawn = False;
  1310. X    else
  1311. X      if (PenHeld)
  1312. X        drawDot();
  1313. X    stroke();
  1314. X    PenIsUp = True;
  1315. X  }
  1316. X}
  1317. X
  1318. X
  1319. X
  1320. X/*
  1321. X
  1322. X  Lower the plotting pen. At least a dot is plotted.
  1323. X
  1324. X*/
  1325. X
  1326. Xvoid lowerPen()
  1327. X
  1328. X{ if (PenIsUp)
  1329. X  { setCurrentPoint(plotterXCoord(PenPosition[X]),
  1330. X                    plotterYCoord(PenPosition[Y]));
  1331. X    PenIsUp = False;
  1332. X  }
  1333. X}
  1334. END_OF_FILE
  1335. if test 11891 -ne `wc -c <'penctrl.c'`; then
  1336.     echo shar: \"'penctrl.c'\" unpacked with wrong size!
  1337. fi
  1338. # end of 'penctrl.c'
  1339. fi
  1340. echo shar: End of archive 5 \(of 6\).
  1341. cp /dev/null ark5isdone
  1342. MISSING=""
  1343. for I in 1 2 3 4 5 6 ; do
  1344.     if test ! -f ark${I}isdone ; then
  1345.     MISSING="${MISSING} ${I}"
  1346.     fi
  1347. done
  1348. if test "${MISSING}" = "" ; then
  1349.     echo You have unpacked all 6 archives.
  1350.     rm -f ark[1-9]isdone
  1351. else
  1352.     echo You still need to unpack the following archives:
  1353.     echo "        " ${MISSING}
  1354. fi
  1355. ##  End of shell archive.
  1356. exit 0
  1357.